import os
from .rw_ini import IniData
from .post_process import *
import cv2
import numpy as np
import time
import tempfile
import shutil
import tqdm
from . import post_process_gray_5fenlei as ppg
from . import mask_refined as mr
from . import pad_filter_edge as pfe
from mmengine.registry import Registry
from .det_infer_multi_batch import det_infer
from .seg_infer_multi_batch import seg_infer
from .det_infer_multi_batch import det_infer_pmi
from .seg_infer_multi_batch import seg_infer
from .cls_infer import cls_infer
from .utils_weice import *
import multiprocessing


def corpped_madian_image_aoi(image,crop_list,filename,label,crop_pad_list,save_crop_pad_path):
    for index , box in enumerate(crop_list):
        box0 = int(box[0])-10
        box1 = int(box[1])-10
        box2 = int(box[2])+10
        box3 = int(box[3])+10
        [box0,box1,box2,box3],error_box = check_bbox_bounds(image,[box0,box1,box2,box3])
        crop_image = image[box1:box3,box0:box2]
        
        name, ext = os.path.splitext(filename)
        cropped_filename = name 
        cropped_filename += "_" + str(label)+"_"+ str(index)+"_"+str(error_box[0])+"_"+str(error_box[1])+"_"+str(error_box[2])+"_"+str(error_box[3])
        crop_madian_name = os.path.join(save_crop_pad_path, cropped_filename)
        crop_madian_name += ext
            
        crop_pad_list.append(crop_madian_name)
        cv2.imwrite(crop_madian_name , crop_image)
    return crop_pad_list


def corpped_pad_image_aoi(image,crop_list,filename,label,crop_image_list,save_crop_path):
    for index , box in enumerate(crop_list):
        box0 = int(box[0])-10
        box1 = int(box[1])-10
        box2 = int(box[2])+10
        box3 = int(box[3])+10
        [box0,box1,box2,box3],error_box = check_bbox_bounds(image,[box0,box1,box2,box3])
        crop_image = image[box1:box3,box0:box2]
        name, ext = os.path.splitext(filename)
        cropped_filename = name 
        cropped_filename += "_" + str(label)+"_"+ str(index)+"_"+str(error_box[0])+"_"+str(error_box[1])+"_"+str(error_box[2])+"_"+str(error_box[3])
        crop_pad_name = os.path.join(save_crop_path, cropped_filename)
        crop_pad_name += ext
        crop_image_list.append(crop_pad_name)
        cv2.imwrite(crop_pad_name , crop_image)
    return crop_image_list


def corpped_nmpad_image_aoi(image,crop_list,filename,label,crop_image_list,save_crop_path, return_box):
    for index , box in enumerate(crop_list):
        box0 = int(box[0])-2
        box1 = int(box[1])-2
        box2 = int(box[2])+2
        box3 = int(box[3])+2
        [box0,box1,box2,box3],error_box = check_bbox_bounds(image,[box0,box1,box2,box3])
        
        crop_image = image[box1:box3,box0:box2]
        # print("error_box",error_box)    
        name, ext = os.path.splitext(filename)
        cropped_filename = name 
        cropped_filename += "_" + str(label)+"_"+ str(index)+"_"+str(error_box[0])+"_"+str(error_box[1])+"_"+str(error_box[2])+"_"+str(error_box[3])
        crop_pad_name = os.path.join(save_crop_path, cropped_filename)
        crop_pad_name += ext
        return_box[crop_pad_name] = [box0,box1,box2,box3]
        # print(crop_pad_name)
        crop_image_list.append(crop_pad_name)
        cv2.imwrite(crop_pad_name , crop_image)
    return crop_image_list, return_box


# pmi,得到所有置信度大于30%的nmpad
def get_nmpad_bbox_pmi(r):
    return_bbox = []
    for image_bbox in r:
        label = image_bbox[0]
        sorce = image_bbox[1]
        bbox = image_bbox[2]
        bbox = [0 if x < 0 else int(x) for x in bbox]
        if label == 3 and sorce >= 0.3:
            return_bbox.append(bbox)
    return return_bbox


def corpped_nmpad_image_pmi(image,crop_list,filename,label,crop_image_list,save_crop_path, return_box):
    for index , box in enumerate(crop_list):
        box0 = int(box[0])-2
        box1 = int(box[1])-2
        box2 = int(box[2])+2
        box3 = int(box[3])+2
        [box0,box1,box2,box3],error_box = check_bbox_bounds(image,[box0,box1,box2,box3]) 
        crop_image = image[box1:box3,box0:box2]
        name, ext = os.path.splitext(filename)
        cropped_filename = name 
        cropped_filename += "_" + str(label)+"_"+ str(index)+"_"+str(error_box[0])+"_"+str(error_box[1])+"_"+str(error_box[2])+"_"+str(error_box[3])
        crop_pad_name = os.path.join(save_crop_path, cropped_filename)
        crop_pad_name += ext
        return_box[crop_pad_name] = [box0,box1,box2,box3]
        crop_image_list.append(crop_pad_name)
        cv2.imwrite(crop_pad_name , crop_image)
    return crop_image_list, return_box


def yolox_run_aoi(det_model,image_paths):
    ini_file = os.path.join(image_paths, "ColorImageGrabingInfo.ini") 
    INI = IniData()
    in_data_list = []
    file_paths = []
    ini_data_list = INI.read_ini_file(ini_file,in_data_list)
    for i in range(in_data_list.__len__()):
        file_paths.append(os.path.join(image_paths, in_data_list[i].filename))
    r = det_infer(det_model,file_paths)
    return r,ini_data_list


def yolox_run_pmi(det_model,file_path,image_files):
    file_paths = [ os.path.join(file_path , item) for item in image_files]
    r = det_infer_pmi(det_model,file_paths)
    return r


# aoi,得到所有置信度大于30%的nmpad
def get_nmpad_bbox(r):
    return_bbox = []
    for image_bbox in r:
        label = image_bbox[0]
        sorce = image_bbox[1]
        bbox = image_bbox[2]
        bbox = [0 if x < 0 else int(x) for x in bbox]
        if label == 2 and sorce >= 0.3:
            return_bbox.append(bbox)
    return return_bbox


def post_process_yolox_aoi(r,ini_data_list,all_info_dict, crop_image_list,crop_pad_list, return_dict_list,file_path,distance, set_num_zhenhen,set_diagonal_length,save_crop_path,save_crop_pad_path):  
    nmpad_bboxes_list = {}
    index_info_dict = {}
    for i in tqdm.tqdm(range(len(r))):
        info_dict ={}
        per_return_dict = {}
        name , result = r[i]
        image = cv2.imread(name)
        if FLAG_SAVE_YOLO_IMAGE:
            image_copy = image.copy()
            for j in range(len(result)):
                label,score ,box = result[j]
                # print(result[j])
                str_show = "label:{0},score:{1}".format(label,round(score,2))
                if label == 3:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 0, 255), 1)
                elif label == 1:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 1)
                elif label == 2:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (255, 0, 0), 1)      
                elif label == 0:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 255), 1)      
                elif label == 4:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (255, 255, 0), 1)
                elif label == 5:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (255, 255, 255), 1)
            cv2.imwrite("AOI_result_test/"+ini_data_list[i].filename, image_copy)
        info_dict['ini_info'] = ini_data_list[i] 
        per_return_dict['filename'] = ini_data_list[i].filename
        per_return_dict['Col'] = ini_data_list[i].Col
        per_return_dict['Row'] = ini_data_list[i].Row
        index_info_dict[ini_data_list[i].filename] = i
        keyichu_back_result, wuran_back_result = ppg.run(result)
        info_dict , per_return_dict = post_all_process_aoi(keyichu_back_result, wuran_back_result,result, ini_data_list[i], image, info_dict,per_return_dict, distance, set_num_zhenhen,set_diagonal_length)
        all_info_dict.append(info_dict)
        return_dict_list.append(per_return_dict)
        zhenhen_bbox = get_nmpad_bbox(result)
        if info_dict["madian_pad"].__len__() != 0:
            crop_pad_list = corpped_madian_image_aoi(image,info_dict["madian_pad"],info_dict["ini_info"].filename,3,crop_pad_list,save_crop_pad_path)
        if zhenhen_bbox.__len__() != 0:
            crop_image_list, nmpad_bboxes_list = corpped_nmpad_image_aoi(image,zhenhen_bbox,info_dict["ini_info"].filename,2,crop_image_list,save_crop_path, nmpad_bboxes_list)
    return all_info_dict , crop_image_list, crop_pad_list, index_info_dict, return_dict_list, nmpad_bboxes_list


def single(start,size,r,ini_data_list,file_path,distance, set_num_zhenhen,set_diagonal_length,save_crop_path,save_crop_pad_path):
    tmp_all_info_dict = []
    tmp_return_dict_list = []
    tmp_index_info_dict = {}
    tmp_crop_image_list = []
    tmp_crop_pad_list =[]
    for i in size:
        index = start + i
        info_dict ={}
        per_return_dict = {}
        name , result = r[index]
        image = cv2.imread(os.path.join(file_path , ini_data_list[index].filename))
        info_dict['ini_info'] = ini_data_list[i] 
        per_return_dict['filename'] = ini_data_list[i].filename
        per_return_dict['Col'] = ini_data_list[i].Col
        per_return_dict['Row'] = ini_data_list[i].Row
        tmp_index_info_dict[ini_data_list[index].filename] = index
        keyichu_back_result, wuran_back_result = ppg.run(result)
        info_dict , per_return_dict = post_all_process_aoi(keyichu_back_result, wuran_back_result,result, ini_data_list[index], image, info_dict,per_return_dict, distance, set_num_zhenhen,set_diagonal_length)
        tmp_all_info_dict.append(info_dict)
        tmp_return_dict_list.append(per_return_dict)
        if info_dict["madian_pad"].__len__() != 0:
            tmp_crop_pad_list = corpped_madian_image_aoi(image,info_dict["madian_pad"],info_dict["ini_info"].filename,3,tmp_crop_pad_list,save_crop_pad_path)        
        if info_dict["zhenhen_crop"].__len__() != 0:
            tmp_crop_image_list = corpped_pad_image_aoi(image,info_dict["zhenhen_crop"],info_dict["ini_info"].filename,2,tmp_crop_image_list,save_crop_path) 
    return tmp_all_info_dict , tmp_crop_image_list, tmp_crop_pad_list, tmp_return_dict_list,tmp_index_info_dict


def post_process_yolox_pmi(r,all_info_dict, crop_image_list, return_dict_list,distance,save_crop_path):  
    nmpad_bboxes_list = {}
    index_info_dict = {}
    for i in range(len(r)):
        info_dict ={}
        per_return_dict = {}
        name , result = r[i]
        image = cv2.imread(name)
        file_name = os.path.basename(name)
        per_return_dict['filename'] = file_name
        index_info_dict[file_name] = i
        if True:
            image_copy = image.copy()
            for j in range(len(result)):
                label,score ,box = result[j]
                if label == 0 or label == 1 or label == 2:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 1)
                elif label == 3:
                    cv2.rectangle(image_copy, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (255, 0, 0), 2)           
            cv2.imwrite("/workspace/ltcv/e2e_gpu/PMI_result/"+file_name, image_copy)
        info_dict , per_return_dict = post_all_process_pmi(result, image, info_dict,per_return_dict, distance)
        all_info_dict.append(info_dict)
        return_dict_list.append(per_return_dict)
        zhenhen_bbox = get_nmpad_bbox_pmi(result)
        if zhenhen_bbox.__len__() != 0:
            crop_image_list, nmpad_bboxes_list = corpped_nmpad_image_pmi(image,zhenhen_bbox,file_name,3,crop_image_list,save_crop_path, nmpad_bboxes_list)
    return all_info_dict , crop_image_list, index_info_dict, return_dict_list, nmpad_bboxes_list


def seg_run_aoi(seg_model,file_paths):
    r = seg_infer(seg_model,file_paths)
    return r    


def cls_run_aoi(cls_model,file_paths):
    with Registry('scope').switch_scope_and_registry('mmcls'):
        r = cls_infer(cls_model,file_paths)
    return r


def seg_run_pmi(seg_model,file_paths):
    r = seg_infer(seg_model,file_paths)
    return r     


# 先构建一个和原始图片大小相同的纯0矩阵A，然后把分割结果根据针痕bbox的位置还原到A矩阵中（加到指定位置），当把所有针痕加到A矩阵后，A矩阵中0值代表非针痕，大于1的值代表针痕，将大于1的值置为1
# 然后根据图片pad的bbox的坐标在A矩阵上进行截图操作，统计截图区域有多少个值是1，所有1值累加则为这个pad上的针痕面积，用针痕面积除以pad面积，则是针痕占比
def post_process_seg_aoi_nmpad(r,all_info_dict,index_info,return_dict,set_area,set_per_area,distance,area_scale, nmpad_bboxes_list, folder_path): 
    # 每批次处理一张图的所有针痕分割结果，所以先根据文件名称合并分割结果
    image_r = {}
    for x in r:
        x_filename = x[0]
        x_basename = os.path.basename(x_filename)
        img_name, _ = os.path.splitext(x_basename)
        img_basename = img_name.split('_')[0]
        if img_basename in image_r:
            image_r[img_basename].append(x)
        else:
            image_r[img_basename] = [x]
    for key, value in image_r.items():
        # 为每张图片创建一个全0值的矩阵
        path_0 = value[0][0]
        filename = os.path.basename(path_0)
        name, ext = os.path.splitext(filename)
        name = name.split('_')[0]
        output_name = name + ext
        image_path = folder_path + output_name
        raw_image = cv2.imread(image_path)
        h, w, c = raw_image.shape
        # print(image_path, raw_image.shape)
        zero_mat = np.zeros((h, w))
        # 得到每张图片的pad位置
        if len(value) != 0:
            # path_0 = value[0][0]
            # filename = os.path.basename(path_0)
            # name, ext = os.path.splitext(filename)
            # name = name.split('_')[0]
            # output_name = name + ext    
            index = index_info[output_name]
            all_pad_bbox = all_info_dict[index]["zhenhen_crop"]
        for path, img in value:
            filename = os.path.basename(path)
            name, ext = os.path.splitext(filename)
            label = name.split('_')[1]
            name = name.split('_')[0]
            if label == "2":
                # nmpad的bbox的坐标
                loc = nmpad_bboxes_list[path]
                # 把针痕的值加到全0矩阵对应的地方
                zero_mat[loc[1]:loc[3], loc[0]:loc[2]] += img
        zero_mat[zero_mat > 0] = 255
        # 遍历所有pad位置，在全0矩阵上做截图，计算针痕面积与pad面积的比
        # image_path = folder_path + output_name
        # raw_image = cv2.imread(image_path)
        zhenhen_crop = [] 
        for index_crop, pad_bbox in enumerate(all_pad_bbox):
            area_pad = (pad_bbox[2] - pad_bbox[0]) * (pad_bbox[3] - pad_bbox[1])
            pad_nmpad_mask = zero_mat[pad_bbox[1]:pad_bbox[3], pad_bbox[0]:pad_bbox[2]]
            pad_nmpad_mask[pad_nmpad_mask>0] = 255
            threshold_img = pad_nmpad_mask
            #计算针痕面积
            global_mask = threshold_img.astype(np.uint8)
            contours, hierarchy = cv2.findContours(global_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
            contours_lists = [contour.tolist() for contour in contours]
            image = raw_image[pad_bbox[1]:pad_bbox[3], pad_bbox[0]:pad_bbox[2], :]
            new_point_list,nmpad_area,perimeter_sum = mr.correct_per_img(image,contours_lists)
            #添加补偿面积
            nmpad_area_add = perimeter_sum*area_scale
            #计算面积占比
            rate = (nmpad_area+nmpad_area_add)/area_pad
            rate = round(rate,2)
            if rate >= set_per_area:
                # contours_lists = [contour.tolist() for contour in contours]
                area = nmpad_area * all_info_dict[index]["ini_info"].PixelSizeX  * all_info_dict[index]["ini_info"].PixelSizeY                
                FaultX = float(all_info_dict[index]["ini_info"].X + all_info_dict[index]["ini_info"].PixelSizeX * ((all_info_dict[index]["zhenhen_crop"][index_crop][0] + all_info_dict[index]["zhenhen_crop"][index_crop][2]) / 2 - 512 / 2))
                FaultY = float(all_info_dict[index]["ini_info"].Y + all_info_dict[index]["ini_info"].PixelSizeY * ((all_info_dict[index]["zhenhen_crop"][index_crop][1] + all_info_dict[index]["zhenhen_crop"][index_crop][3]) / 2 - 384 / 2))
                orignal_box = pad_bbox
                zhenhen_crop.append([new_point_list,[FaultX, FaultY],orignal_box,rate])
        if "zhenhen_crop" not in return_dict[index]:
            return_dict[index]["zhenhen_crop"] = []
        return_dict[index]["zhenhen_crop"].extend(zhenhen_crop)
    return return_dict


# 先构建一个和原始图片大小相同的纯0矩阵A，然后把分割结果根据针痕bbox的位置还原到A矩阵中（加到指定位置），当把所有针痕加到A矩阵后，A矩阵中0值代表非针痕，大于1的值代表针痕，将大于1的值置为1
# 然后根据图片pad的bbox的坐标在A矩阵上进行截图操作，统计截图区域有多少个值是1，所有1值累加则为这个pad上的针痕面积，用针痕面积除以pad面积，则是针痕占比
def post_process_seg_pmi_nmpad(r,all_info_dict,index_info,return_dict,set_per_area,area_scale, nmpad_bboxes_list, folder_path): 
    # 每批次处理一张图的所有针痕分割结果，所以先根据文件名称合并分割结果
    image_r = {}
    for x in r:
        x_filename = x[0]
        x_basename = os.path.basename(x_filename)
        img_name, _ = os.path.splitext(x_basename)
        img_basename = img_name.split('_')[0]
        if img_basename in image_r:
            image_r[img_basename].append(x)
        else:
            image_r[img_basename] = [x]
    for key, value in image_r.items():
        # 为每张图片创建一个全0值的矩阵
        zero_mat = np.zeros((480, 480))
        # 得到每张图片的pad位置
        if len(value) != 0:
            path_0 = value[0][0]
            filename = os.path.basename(path_0)
            name, ext = os.path.splitext(filename)
            name = name.split('_')[0]
            output_name = name + ext
            index = index_info[output_name]
            all_pad_bbox = all_info_dict[index]["zhenhen_crop"]
        for path, img in value:
            filename = os.path.basename(path)
            name, ext = os.path.splitext(filename)
            label = name.split('_')[1]
            name = name.split('_')[0]
            if label == "3":
                # nmpad的bbox的坐标
                loc = nmpad_bboxes_list[path]
                # 把针痕的值加到全0矩阵对应的地方
                zero_mat[loc[1]:loc[3], loc[0]:loc[2]] += img
        zero_mat[zero_mat > 0] = 1
        # 遍历所有pad位置，在全0矩阵上做截图，计算针痕面积与pad面积的比
        image_path = folder_path + output_name
        raw_image = cv2.imread(image_path)
        zhenhen_crop = [] 
        for index_crop, pad_info in enumerate(all_pad_bbox):
            pad_bbox = pad_info[0]
            area_pad = pad_info[1]
            pad_nmpad_mask = zero_mat[pad_bbox[1]:pad_bbox[3], pad_bbox[0]:pad_bbox[2]]
            #计算针痕面积
            global_mask = pad_nmpad_mask.astype(np.uint8)
            contours, hierarchy = cv2.findContours(global_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
            contours_lists_model = [contour.tolist() for contour in contours]
            image = raw_image[pad_bbox[1]:pad_bbox[3], pad_bbox[0]:pad_bbox[2], :]
            contours_lists,nmpad_area,perimeter_sum = mr.correct_per_img_pmi(image,contours_lists_model)
            nmpad_area_model = np.sum(np.where(pad_nmpad_mask == 1, 1, 0)) # 统计等于 1 的元素个数
            if nmpad_area < nmpad_area_model*0.8:
                contours_lists = contours_lists_model
                nmpad_area = nmpad_area_model
            #添加补偿面积
            nmpad_area_add = nmpad_area*area_scale
            #计算面积占比
            rate = (nmpad_area+nmpad_area_add)/area_pad
            rate = round(rate,2)
            if rate >= set_per_area:
                # contours_lists = [contour.tolist() for contour in contours]
                orignal_box = pad_bbox
                zhenhen_crop.append([contours_lists,orignal_box,rate])
        if "zhenhen_crop" not in return_dict[index]:
            return_dict[index]["zhenhen_crop"] = []
        return_dict[index]["zhenhen_crop"].extend(zhenhen_crop)
    return return_dict

def post_process_cls_aoi(r,all_info_dict,index_info,return_dict, ini_data_list, folder_path):
    # 处理ini_data_list，创建一个文件名：下标的字典，方便查询用
    ini_dict = {}
    for index, ini_data in enumerate(ini_data_list):
        filename = ini_data.filename
        ini_dict[filename] = index
    num = 0
    for path, result in r:
        madian_box = []
        file_name_parts = path.split("/")
        filename = os.path.basename(path)
        name, ext = os.path.splitext(filename)
        err_x1 = name.split('_')[3]
        err_y1 = name.split('_')[4]
        err_x2 = name.split('_')[5]
        err_y2 = name.split('_')[6]
        name = name.split('_')[0]
        output_name = name + ext    
        ini_data = ini_data_list[ini_dict[output_name]]
        image = cv2.imread(os.path.join(folder_path, output_name))
        index = index_info[output_name]
        index_crop = int(file_name_parts[-1].split("_")[2].split(".")[0])
        error_info = [err_x1,err_y1,err_x2,err_y2]
        if result[0] == 1:
            orignal_box = [all_info_dict[index]["madian_pad"][index_crop][0],all_info_dict[index]["madian_pad"][index_crop][1],all_info_dict[index]["madian_pad"][index_crop][2],all_info_dict[index]["madian_pad"][index_crop][3]]
            madian_box.append([orignal_box])
        elif result[0] == 2 or result[0] == 3: 
            # 添加cv判断边缘
            if not pfe.find_pad(path,error_info): 
                orignal_box = [all_info_dict[index]["madian_pad"][index_crop][0],all_info_dict[index]["madian_pad"][index_crop][1],all_info_dict[index]["madian_pad"][index_crop][2],all_info_dict[index]["madian_pad"][index_crop][3]]
                madian_box.append([orignal_box])
        num += 1
        if "madian_box" not in return_dict[index]:
            return_dict[index]["madian_box"] = []
        if madian_box == []:
            return_dict[index]["madian_box"].extend(madian_box)
        else:
            box_zhenhen = madian_box[0][0]
            FaultX = float(ini_data.X + ini_data.PixelSizeX * ((box_zhenhen[0] + box_zhenhen[2]) / 2 - image.shape[1] / 2))
            FaultY = float(ini_data.Y + ini_data.PixelSizeY * ((box_zhenhen[1] + box_zhenhen[3]) / 2 - image.shape[0] / 2))
            madian_box[0].append([FaultX, FaultY])
            return_dict[index]["madian_box"].extend(madian_box)
    return return_dict     


def run_pmi(det_model,seg_model,folder_path,image_files,distance,set_per_area,area_scale):
    all_info_list = []
    crop_image_list = []
    return_dict_list = []
    # 临时存储图片地址
    save_crop_path = tempfile.mkdtemp()
    t_begin = time.time()
    t_det_begin = t_begin
    # 检测模型推理结果
    r_yolox = yolox_run_pmi(det_model,folder_path,image_files)
    t_det_end = time.time()
    print(f'pmi run det time: {t_det_end-t_det_begin}')
    t_process_det_begin = time.time()
    # 检测模型结果后处理
    all_info_list , crop_image_list ,index_info_dict ,return_dict_list, nmpad_bboxes_list = post_process_yolox_pmi(r_yolox,all_info_list, crop_image_list, return_dict_list,distance,save_crop_path)
    t_process_det_end = time.time()
    print(f'pmi process det time: {t_process_det_end-t_process_det_begin}')
    t_seg_begin = time.time()
    # 分割模型推理结果
    r_seg = seg_run_pmi(seg_model,crop_image_list)
    t_seg_end = time.time()
    print(f'pmi run seg time: {t_seg_end-t_seg_begin}')
    t_process_seg_begin = time.time()
    # 分割模型结果后处理
    return_dict_list = post_process_seg_pmi_nmpad(r_seg, all_info_list, index_info_dict, return_dict_list,set_per_area,area_scale, nmpad_bboxes_list, folder_path)
    t_process_seg_end = time.time()
    print(f'pmi process seg time: {t_process_seg_end-t_process_seg_begin}')
    t_end = t_process_seg_end
    print(f'e2e time is: {t_end-t_begin}')
    # 删除临时图片并返回结果
    shutil.rmtree(save_crop_path)
    return return_dict_list


# def run_aoi(yolox_model,seg_model,cls_model,folder_path,distance,set_num_zhenhen,set_diagonal_length,set_area,set_per_area):
def run_aoi(det_model,seg_model,cls_model,folder_path,distance,set_num_zhenhen,set_diagonal_length,set_area,set_per_area,area_scale):
    # init list 
    all_info_list = []
    crop_image_list = []
    crop_pad_list = []
    return_dict_list = []
    start_time = time.time()
    save_crop_path = tempfile.mkdtemp()
    save_crop_pad_path = tempfile.mkdtemp()
    # run yolox 
    start_yolox_run_time = time.time()
    r_yolox, ini_data_list = yolox_run_aoi(det_model,folder_path)
    end_yolox_run_time = time.time()
    yolox_run_time = end_yolox_run_time - start_yolox_run_time
    print("yolox_run_time:{0}".format(yolox_run_time) + "[sec]")
    # post process yolox
    start_post_process_yolox_time = time.time()
    #单进程
    all_info_list , crop_image_list, crop_pad_list, index_info_dict ,return_dict_list,  nmpad_bboxes_list = post_process_yolox_aoi(r_yolox,ini_data_list,all_info_list, crop_image_list,crop_pad_list, return_dict_list,folder_path,distance, set_num_zhenhen,set_diagonal_length,save_crop_path,save_crop_pad_path)
    end_post_process_yolox_time = time.time()
    post_process_yolox_time = end_post_process_yolox_time - start_post_process_yolox_time
    print("post_process_yolox_time:{0}".format(post_process_yolox_time) + "[sec]")
    # run seg
    start_seg_run_time = time.time()
    r_seg = seg_run_aoi(seg_model,crop_image_list)
    end_seg_run_time = time.time()
    seg_run_time = end_seg_run_time - start_seg_run_time
    print("seg_run_time:{0}".format(seg_run_time) + "[sec]")
    # post process seg
    start_post_process_seg_time = time.time()
    return_dict_list = post_process_seg_aoi_nmpad(r_seg, all_info_list, index_info_dict, return_dict_list,set_area,set_per_area,distance,area_scale, nmpad_bboxes_list, folder_path)
    end_post_process_seg_time = time.time()
    post_process_seg_time = end_post_process_seg_time - start_post_process_seg_time
    print("post_process_seg_time:{0}".format(post_process_seg_time) + "[sec]")
    # run cls
    start_cls_run_time = time.time()
    r_cls = cls_run_aoi(cls_model,crop_pad_list)
    end_cls_run_time = time.time()
    cls_run_time = end_cls_run_time - start_cls_run_time
    print("cls_run_time:{0}".format(cls_run_time) + "[sec]")
    start_cls_post_process_time = time.time()
    return_dict_list = post_process_cls_aoi(r_cls, all_info_list, index_info_dict, return_dict_list, ini_data_list, folder_path)
    end_cls_post_process_time = time.time()
    cls_post_process_time = end_cls_post_process_time - start_cls_post_process_time
    print("cls_post_process_time:{0}".format(cls_post_process_time) + "[sec]")
    end_time = time.time()
    e2e_time = end_time - start_time
    print("e2e_time:{0}".format(e2e_time) + "[sec]")
    shutil.rmtree(save_crop_pad_path)
    shutil.rmtree(save_crop_path)
    return return_dict_list
